package com.dd.admin.business.storage.controller;

import com.dd.admin.business.storage.dto.FileUploadDto;
import com.dd.admin.business.storage.service.QiniuStorageService;
import com.dd.admin.business.storage.vo.FileInfoVo;
import com.dd.admin.common.model.result.ResultBean;
import com.qiniu.storage.model.FileInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 七牛云存储控制器
 * 提供文件上传、删除、查询等功能的API接口
 */
@Slf4j
@RestController
@RequestMapping("/api/storage")
@Api(tags = "七牛云存储管理")
@CrossOrigin
@Validated
public class QiniuStorageController {

    @Autowired
    private QiniuStorageService qiniuStorageService;

    /**
     * 上传文件
     */
    @PostMapping("/upload")
    @ApiOperation("上传文件")
    public ResultBean<Map<String, Object>> uploadFile(
            @ApiParam("文件") @RequestParam("file") MultipartFile file,
            @ApiParam("文件名") @RequestParam(value = "fileName", required = false) String fileName,
            @ApiParam("存储目录") @RequestParam(value = "directory", required = false) String directory) {
        
        log.info("接收文件上传请求，文件名：{}，目录：{}", fileName, directory);
        
        if (file.isEmpty()) {
            return ResultBean.error("上传文件不能为空");
        }
        
        try {
            String fileUrl = qiniuStorageService.uploadFile(file, fileName, directory);
            
            Map<String, Object> result = new HashMap<>();
            result.put("fileUrl", fileUrl);
            result.put("fileName", fileName);
            result.put("directory", directory);
            result.put("fileSize", file.getSize());
            result.put("originalName", file.getOriginalFilename());
            
            log.info("文件上传成功，返回结果：{}", result);
            return ResultBean.success(result);
            
        } catch (Exception ex) {
            log.error("文件上传失败：", ex);
            return ResultBean.error("文件上传失败：" + ex.getMessage());
        }
    }

    /**
     * 删除文件
     */
    @PostMapping("/delete")
    @ApiOperation("删除文件")
    public ResultBean<Boolean> deleteFile(
            @ApiParam("文件目录") @RequestParam(value = "directory", required = false) String directory,
            @ApiParam("文件名") @RequestParam("fileName") String fileName) {
        
        log.info("接收文件删除请求，目录：{}，文件名：{}", directory, fileName);
        
        try {
            boolean success = qiniuStorageService.deleteFile(directory, fileName);
            
            if (success) {
                log.info("文件删除成功");
                return ResultBean.success(true);
            } else {
                log.warn("文件删除失败");
                return ResultBean.error("文件删除失败");
            }
            
        } catch (Exception ex) {
            log.error("文件删除异常：", ex);
            return ResultBean.error("文件删除失败：" + ex.getMessage());
        }
    }

    /**
     * 获取目录列表
     */
    @GetMapping("/directories")
    @ApiOperation("获取目录列表")
    public ResultBean<List<String>> getDirectories() {
        
        log.info("接收获取目录列表请求");
        
        try {
            List<String> directories = qiniuStorageService.getDirectoryList();
            
            log.info("获取目录列表成功，共{}个目录", directories.size());
            return ResultBean.success(directories);
            
        } catch (Exception ex) {
            log.error("获取目录列表失败：", ex);
            return ResultBean.error("获取目录列表失败：" + ex.getMessage());
        }
    }

    /**
     * 获取文件列表
     */
    @GetMapping("/files")
    @ApiOperation("获取文件列表")
    public ResultBean<List<FileInfoVo>> getFiles(
            @ApiParam("目录前缀") @RequestParam(value = "directory", required = false) String directory) {
        
        log.info("接收获取文件列表请求，目录：{}", directory);
        
        try {
            List<FileInfo> fileInfos = qiniuStorageService.getFileList(directory);
            
            // 转换为VO对象
            List<FileInfoVo> result = new ArrayList<>();
            for (FileInfo fileInfo : fileInfos) {
                FileInfoVo vo = new FileInfoVo();
                vo.setKey(fileInfo.key);
                vo.setFileName(getFileNameFromKey(fileInfo.key));
                vo.setFileSize(fileInfo.fsize);
                vo.setMimeType(fileInfo.mimeType);
                vo.setPutTime(fileInfo.putTime);
                vo.setHash(fileInfo.hash);
                // 生成文件访问URL（这里假设是公开空间，如果是私有空间需要生成token）
                vo.setFileUrl("https://" + fileInfo.key); // 这里需要根据实际域名配置
                result.add(vo);
            }
            
            log.info("获取文件列表成功，共{}个文件", result.size());
            return ResultBean.success(result);
            
        } catch (Exception ex) {
            log.error("获取文件列表失败：", ex);
            return ResultBean.error("获取文件列表失败：" + ex.getMessage());
        }
    }

    /**
     * 生成文件访问token（用于私有空间）
     */
    @GetMapping("/token")
    @ApiOperation("生成文件访问token")
    public ResultBean<Map<String, Object>> generateAccessToken(
            @ApiParam("文件目录") @RequestParam(value = "directory", required = false) String directory,
            @ApiParam("文件名") @RequestParam("fileName") String fileName,
            @ApiParam("过期时间（秒）") @RequestParam(value = "expireInSeconds", defaultValue = "600") Long expireInSeconds) {
        
        log.info("接收生成访问token请求，目录：{}，文件名：{}，过期时间：{}秒", directory, fileName, expireInSeconds);
        
        try {
            String tokenUrl = qiniuStorageService.generateAccessToken(directory, fileName, expireInSeconds);
            
            Map<String, Object> result = new HashMap<>();
            result.put("tokenUrl", tokenUrl);
            result.put("expireInSeconds", expireInSeconds);
            result.put("fileName", fileName);
            result.put("directory", directory);
            
            log.info("生成访问token成功");
            return ResultBean.success(result);
            
        } catch (Exception ex) {
            log.error("生成访问token失败：", ex);
            return ResultBean.error("生成访问token失败：" + ex.getMessage());
        }
    }

    /**
     * 测试接口
     */
    @GetMapping("/test")
    @ApiOperation("测试接口")
    public ResultBean<String> test() {
        log.info("七牛云存储服务测试接口调用");
        return ResultBean.success("七牛云存储服务运行正常");
    }

    /**
     * 从文件key中提取文件名
     */
    private String getFileNameFromKey(String key) {
        if (key == null || key.isEmpty()) {
            return "";
        }
        
        int lastSlashIndex = key.lastIndexOf("/");
        if (lastSlashIndex >= 0 && lastSlashIndex < key.length() - 1) {
            return key.substring(lastSlashIndex + 1);
        }
        
        return key;
    }
}